<?php
/**
 * +----------------------------------------------------------------------
 * | 自定义标签
 * +----------------------------------------------------------------------
 */
namespace app\home\taglib;

use think\template\TagLib;

class Tp extends TagLib {

    protected $tags = array(
        // 标签定义： attr 属性列表 close 是否闭合（0 或者1 默认1） alias 标签别名 level 嵌套层次
        'close'     => ['attr' => 'time,format', 'close' => 0],                           //闭合标签，默认为不闭合
        'open'      => ['attr' => 'name,type', 'close' => 1],
        'block'     => ['attr' => 'name,type,id','close' => 1],                           //获取区块信息
        'widget'    => ['attr' => 'name', 'close' => 1],
        'hook'      => ['attr' => 'name,param,once', 'close' => 0],
        'captcha'   => ['attr' => 'height,width', 'close' => 0],//非必须属性font-size,length,bg,id
        'config'    => ['attr' => 'name,type','close' => 0],                              //获取系统信息
        'nav'       => ['attr' => 'id,limit', 'close' => 1],                              //获取导航信息
        //'cate'      => ['attr' => 'id,type','close' => 0],                                //通用栏目信息
        //'position'  => ['attr' => 'name','close' => 1],                                   //通用位置信息
        'list'      => ['attr' => 'id,name,pagesize,where,limit,order','close' => 1],     //通用列表
        //'search'    => ['attr' => 'search,table,name,pagesize,where,order','close' => 1], //通用搜索
        //'tag'       => ['attr' => 'name,pagesize,order','close' => 1],                    //通用标签
        //'prev'	    => ['attr'	=> 'len','close' => 0],                                   //上一篇
        //'next'	    => ['attr'	=> 'len','close' => 0],                                   //下一篇
    );

    /**
     * 这是一个闭合标签的简单演示
     */
    public function tagClose($tag)
    {
        $format = empty($tag['format']) ? 'Y-m-d H:i:s' : $tag['format'];
        $time = empty($tag['time']) ? time() : $tag['time'];
        $parse = '<?php ';
        $parse .= 'echo date("' . $format . '",' . $time . ');';
        $parse .= ' ?>';
        return $parse;
    }

    /**
     * 这是一个非闭合标签的简单演示
     */
    public function tagOpen($tag, $content)
    {
        $type = empty($tag['type']) ? 0 : 1; // 这个type目的是为了区分类型，一般来源是数据库
        $name = $tag['name']; // name是必填项，这里不做判断了
        $parse = '<?php ';
        $parse .= '$test_arr=[[1,3,5,7,9],[2,4,6,8,10]];'; // 这里是模拟数据
        $parse .= '$__LIST__ = $test_arr[' . $type . '];';
        $parse .= ' ?>';
        $parse .= '{volist name="__LIST__" id="' . $name . '"}';
        $parse .= $content;
        $parse .= '{/volist}';
        return $parse;
    }

    /**
     * 组件标签
     */
    public function tagWidget($tag, $content)
    {
        if (empty($tag['name'])) {
            return '';
        }
        $name = $tag['name'];
        if (strpos($name, '$') === 0) {
            $this->autoBuildVar($name);
        } else {
            $name = "'{$name}'";
        }
        $parse = <<<parse
        <?php
            if(isset(\$theme_widgets[{$name}]) && \$theme_widgets[{$name}]['display']){
                \$widget=\$theme_widgets[{$name}];
            
        ?>
        {$content}
        <?php
            }
        ?>
parse;
        return $parse;
    }

    public function tagHook($tag, $content)
    {
        $name  = empty($tag['name']) ? '' : $tag['name'];
        $param = empty($tag['param']) ? '' : $tag['param'];
        $once  = empty($tag['once']) ? 'false' : 'true';

        if (empty($param)) {
            $param = 'null';
        } else if (strpos($param, '$') === false) {
            $this->autoBuildVar($param);
        }

        $parse = <<<parse
        <php>
            \\think\\facade\\Hook::listen('{$name}',{$param},{$once});
        </php>
parse;
        return $parse;
    }

    // 通用碎片信息
    public function tagConfig($tag)
    {
        $name   = $tag['name'] ?: '';
        $type   = $tag['type'] ?: '';
        $str = '<?php ';
        $str .= 'echo \think\facade\Db::name("systems")->where("name",\''.$name.'\')->value("'.$type.'");';
        $str .= '?>';
        return $str;
    }

    /**
     * 区块信息标签
     */
    public function tagBlock($tag, $content)
    {
        $name   = $tag['name'] ?? 'vo';
        $type   = $tag['type'] ?? 1;
        $id     = $tag['id'] ?? '';
        $parse  = '<?php ';
        $parse .= '
            $__WHERE__ = array();
            if (!empty(\''.$id.'\')) {
                $__WHERE__[] = [\'id\', \'=\', '.$id.'];
            }
            if (!empty(\''.$type.'\')) {
                $__WHERE__[] = [\'slide_id\', \'=\', \''.$type.'\'];
            }
            $__WHERE__[] = [\'status\', \'=\', 1];';
        $parse .= '$__LIST__ = \think\facade\Db::name(\'slide_item\')->where($__WHERE__)->order(\'sort ASC,id desc\')->select();';
        $parse .= ' ?>';
        $parse .= '{volist name="__LIST__" id="' . $name . '"}';
        $parse .= $content;
        $parse .= '{/volist}';
        return $parse;
    }

    // 通用导航信息
    public function tagNav($tag, $content)
    {
        $limit = isset($tag['limit']) ? $tag['limit'] : '0';
        $id    = isset($tag['id'])    ? $tag['id']    : '';
        $name  = isset($tag['name'])  ? $tag['name']  : 'nav';

        $parse  = '<?php ';
        $parse .= '$__LIST__ = \think\facade\Db::name(\'article_category\')
                ->field(\'id,name\')
                ->where(\'status\',1)->order(\'sort ASC,id DESC\')->limit(\''.$limit.'\')->select();';
        $parse .= ' ?>';
        $parse .= '{volist name="__LIST__" id="' . $name . '"}';
        $parse .= $content;
        $parse .= '{/volist}';
        return $parse;
    }

    // 文章列表
    public function tagList($tag, $content)
    {
        $id    = $tag['cateid'] ?? 0;                            //可以为空
        $name  = $tag['name'] ?? "list";                         //不可为空
        $order = $tag['order'] ?? 'sort ASC,id DESC';            //排序
        $limit = $tag['limit'] ?? 0;                             //多少条数据,传递时不再进行分页
        $where = isset($tag['where']) ?  $tag['where'].' AND a.status = 1 ' : 'a.status = 1'; //查询条件
        //获取分类
        if ($id) {
            $ids = \think\facade\Db::name('article_category')->where('id|parent_id','=', $id)->column('id');
            $ids = implode(',', $ids);
            $where .= 'AND category_id IN (' . $ids . ')';
        }
        $pagesize = $tag['pagesize'] ?? 10;
        $parse  = '<?php ';
        $parse .='
            //当传递limit时，不再进行分页
            if('.$limit.'!=0){
                $__LIST__ = \think\facade\Db::name(\'article\')
                ->alias(\'a\')
                ->join(\'article_category c \',\'a.category_id= c.id\')
                ->join(\'user u \',\'a.user_id= u.id\')
                ->field(\'a.*,c.name,u.username,u.avatar\')
                ->order(\''.$order.'\')
                ->limit(\''.$limit.'\')
                ->whereRaw(" '.$where.'")
                ->select();
                $page = \'\';
            }else{
                $__LIST__ = \think\facade\Db::name(\'article\')
                ->alias(\'a\')
                ->join(\'article_category c \',\'a.category_id= c.id\')
                ->join(\'user u \',\'a.user_id= u.id\')
                ->field(\'a.*,c.name,u.username,u.avatar\')
                ->order(\''.$order.'\')
                ->whereRaw(" '.$where.'")
                ->paginate('.$pagesize.', false, [\'query\' => request()->param()]);
                $page = $__LIST__->render();
            }
            ';
        $parse .= ' ?>';
        $parse .= '{volist name="__LIST__" id="'.$name.'"}';
        $parse .= $content;
        $parse .= '{/volist}';
        return $parse;
    }

    public function tagCaptcha($tag, $content)
    {
        //height,width,font-size,length,bg,id
        $id       = empty($tag['id']) ? '' : $tag['id'];
        $paramId  = empty($tag['id']) ? '' : '&id=' . $tag['id'];
        $height   = empty($tag['height']) ? '' : '&height=' . $tag['height'];
        $width    = empty($tag['width']) ? '' : '&width=' . $tag['width'];
        $fontSize = empty($tag['font-size']) ? '' : '&font_size=' . $tag['font-size'];
        $length   = empty($tag['length']) ? '' : '&length=' . $tag['length'];
        $bg       = empty($tag['bg']) ? '' : '&bg=' . $tag['bg'];
        $title    = empty($tag['title']) ? '换一张' : $tag['title'];
        $style    = empty($tag['style']) ? 'cursor: pointer;' : $tag['style'];
        $params   = ltrim("{$paramId}{$height}{$width}{$fontSize}{$length}{$bg}", '&');
        $parse    = <<<parse
        <php>\$__CAPTCHA_SRC=url('/new_captcha').'?{$params}';</php>
        <img src="{\$__CAPTCHA_SRC}" onclick="this.src='{\$__CAPTCHA_SRC}&time='+Math.random();" title="{$title}" class="captcha captcha-img verify_img" style="{$style}"/>{$content}
        <input type="hidden" name="_captcha_id" value="{$id}">
parse;
        return $parse;
    }

    // 通用栏目信息
    Public function qtagCate($tag){
        $id   = isset($tag['id']) ? $tag['id']   : "input('cate')";
        $type = $tag['type']      ? $tag['type'] : 'catname';

        $str = '<?php ';
        $str .= '$__CATE__=\think\facade\Db::name("cate")->where("id",'.$id.')->find();';
        $str .= 'if (is_array($__CATE__)) { ';
        $str .= '$__CATE__[\'url\']=getUrl($__CATE__);';
        $str .= 'echo $__CATE__[\''.$type.'\'];';
        $str .= '}';
        $str .= '?>';
        return $str;
    }

    // 通用位置信息
    Public function qtagPosition($tag, $content){
        $name   = $tag['name'] ? $tag['name'] : 'position';
        $parse  = '<?php ';
        $parse .= '$__CATE__ = \think\facade\Db::name(\'cate\')->select();';
        $parse .= '$__LIST__ = getParents($__CATE__,input(\'cate\'));';
        $parse .= ' ?>';
        $parse .= '{volist name="__LIST__" id="' . $name . '"}';
        $parse .= '<?php $' . $name . '[\'url\']=getUrl( $' . $name . '); ?>';
        $parse .= $content;
        $parse .= '{/volist}';
        return $parse;
    }

    // 通用搜索 search,table,name,pagesize,where,order
    Public function qtagSearch($tag, $content){
        $search   = isset($tag['search'])   ? $tag['search']                    : "";                     //关键字
        $table    = isset($tag['table'])    ? $tag['table']                     : "article";              //表名称
        $name     = isset($tag['name'])     ?  $tag['name']                     : "list";                 //不可为空
        $order    = isset($tag['order'])    ?  $tag['order']                    : 'sort ASC,id DESC';     //排序
        $where    = isset($tag['where'])    ?  $tag['where'].' AND status = 1 ' : 'status = 1';           //查询条件
        $pagesize = isset($tag['pagesize']) ?  $tag['pagesize']                 : config('app.page_size');

        $parse  = '<?php ';
        $parse .='
                $__MODULEID__ = \think\facade\Db::name("module")->where("name","' . $table . '")->value("id");
                $__LIST__ = \think\facade\Db::name("' . $table . '")
                ->order("' . $order . '")
                ->where("' . $where . '")
                ->where("title", "like", "%' . $search . '%")
                ->paginate("' . $pagesize . '",false,[\'query\' => request()->param()]);
                $page = $__LIST__->render();

                //处理数据（把列表中需要处理的字段转换成数组和对应的值）
                $__LIST__ = changeFields($__LIST__,$__MODULEID__);
            ';
        $parse .= ' ?>';
        $parse .= '{volist name="__LIST__" id="'.$name.'"}';
        $parse .= $content;
        $parse .= '{/volist}';
        return $parse;
    }

    // 通用标签 search,table,name,pagesize,where,order
    Public function qtagTag($tag, $content){
        $name     = isset($tag['name'])     ?  $tag['name']                     : "list";                 //不可为空
        $order    = isset($tag['order'])    ?  $tag['order']                    : 'sort ASC,id DESC';     //排序
        $pagesize = isset($tag['pagesize']) ?  $tag['pagesize']                 : config('app.page_size');

        $parse  = '<?php ';
        $parse .='
                //获取模型ID
                $__MODULEID__ = request()->param(\'module\');
                //获取搜索词
                $__T__ = request()->param(\'t\');
                //查询模型的表名称
                $__MODULENAME__ = \think\facade\Db::name(\'module\')
                    ->where(\'id\', $__MODULEID__)
                    ->value(\'name\');
                //查询搜索词对应的ID
                $__TAGID__ = \think\facade\Db::name(\'tags\')
                    ->where(\'module_id\', $__MODULEID__)
                    ->where(\'name\', $__T__)
                    ->value(\'id\');
                //查询tag字段名称
                $__TAGFIELD__ = \think\facade\Db::name(\'field\')
                    ->where(\'moduleid\', $__MODULEID__)
                    ->where(\'type\', \'tag\')
                    ->value(\'field\');

                $__LIST__ = \think\facade\Db::name($__MODULENAME__)
                ->order("' . $order . '")
                ->where($__TAGFIELD__, "find in set", $__TAGID__)
                ->paginate("' . $pagesize . '", false, [\'query\' => request()->param()]);
                $page = $__LIST__->render();

                //处理数据（把列表中需要处理的字段转换成数组和对应的值）
                $__LIST__ = changeFields($__LIST__,$__MODULEID__);
            ';
        $parse .= ' ?>';
        $parse .= '{volist name="__LIST__" id="'.$name.'"}';
        $parse .= $content;
        $parse .= '{/volist}';
        return $parse;
    }

    // 详情上一篇
    Public function qtagPrev($tag){
        $len = $tag['len'] ? $tag['len'] : '500';

        $str  = '<?php ';
        $str .= '
                //查找表名称
                $__TABLENAME__ = \think\facade\Db::name(\'cate\')
                    ->alias(\'c\')
                    ->leftJoin(\'module m\',\'c.moduleid = m.id\')
                    ->field(\'m.name as table_name\')
                    ->where(\'c.id\',input(\'cate\'))
                    ->find();
                //根据ID查找上一篇的信息
                $__PREV__ = \think\facade\Db::name($__TABLENAME__[\'table_name\'])
                    ->where(\'cate_id\',input(\'cate\'))
                    ->where(\'id\',\'<\',input(\'id\'))
                    ->where(\'status\',\'=\',1)
                    ->field(\'id,cate_id,title\')
                    ->order(\'sort ASC,id DESC\')
                    ->find();
                if($__PREV__){
                    //处理字数
                    if('.$len.'<>500){
                       $__PREV__[\'title\'] = mb_substr($__PREV__[\'title\'],0,'.$len.');
                    }
                    //处理上一篇中的URL
                    $__PREV__[\'url\'] = getShowUrl($__PREV__);
                    $__PREV__ = "<a class=\"prev\" title=\" ".$__PREV__[\'title\']." \" href=\" ".$__PREV__[\'url\']." \">".$__PREV__[\'title\']."</a>";
                }else{
                    $__PREV__ = "<a class=\"prev_no\" href=\"javascript:;\">暂无数据</a>";
                }
                echo $__PREV__;
                ';
        $str .= '?>';
        return $str;
    }

    // 详情下一篇
    Public function qtagNext($tag){
        $len = $tag['len'] ? $tag['len'] : '500';

        $str  = '<?php ';
        $str .= '
                //查找表名称
                $__TABLENAME__ = \think\facade\Db::name(\'cate\')
                    ->alias(\'c\')
                    ->leftJoin(\'module m\',\'c.moduleid = m.id\')
                    ->field(\'m.name as table_name\')
                    ->where(\'c.id\',input(\'cate\'))
                    ->find();
                //根据ID查找下一篇的信息
                $__PREV__ = \think\facade\Db::name($__TABLENAME__[\'table_name\'])
                    ->where(\'cate_id\',input(\'cate\'))
                    ->where(\'id\',\'>\',input(\'id\'))
                    ->where(\'status\',\'=\',1)
                    ->field(\'id,cate_id,title\')
                    ->order(\'sort ASC,id DESC\')
                    ->find();
                if($__PREV__){
                    //处理字数
                    if('.$len.'<>500){
                       $__PREV__[\'title\'] = mb_substr($__PREV__[\'title\'],0,'.$len.');
                    }
                    //处理下一篇中的URL
                    $__PREV__[\'url\'] = getShowUrl($__PREV__);
                    $__PREV__ = "<a class=\"next\" title=\" ".$__PREV__[\'title\']." \" href=\" ".$__PREV__[\'url\']." \">".$__PREV__[\'title\']."</a>";
                }else{
                    $__PREV__ = "<a class=\"next_no\" href=\"javascript:;\">暂无数据</a>";
                }
                echo $__PREV__;
                ';
        $str .= '?>';
        return $str;
    }
}